﻿#include "stdafx.h"
#include "ClassContext.h"
#include "ClassInstanceType.h"
#include "AstDef.h"
#include "AstClass.h"
#include "AstFunction.h"
#include "AstProtected.h"
#include "AstDef.h"
#include "AstCall.h"
#include "Parameter.h"
#include "AutoType.h"
#include "CodeGenerate/NewGen.h"

/// <summary>
///  按函数签名保存
/// </summary>
std::unordered_map<std::string, ClassInstanceType*> classInstances;

CodeGen * AstClass::makeGen(SiContext * parent)
{
	parent->setClass(name, this);
	_parent = parent;

	for (auto i : block) {
		// 检测构造函数
		auto *p=dynamic_cast<AstFunction*>(i);
		if (p) {
			if (p->name == ":init") {
				_construstors.push_back(p);
			}
			continue;
		}	  
		// 检测是否模版类
		auto *q = dynamic_cast<AstDef*>(i);
		if (q) {
			if (!q->type || AstType::AutoTyId == q->type->type())
				_templated = true;
		}
	}

	return nullptr;
}

ClassInstanceType * AstClass::getInstance(std::vector<std::pair<std::string, CodeGen*>>& args) {
	auto x = getCreaterOrderd(args);
	auto* creater = x.first;

	// TODO: 判断更准确 creater 应该为默认构造函数
	if (!args.empty() && !creater)
		return nullptr;  // 不匹配

	// 推导类
	auto a = generateClass(creater, x.second);
	return a.first;
}

CodeGen * AstClass::makeNew(std::vector<std::pair<std::string, CodeGen*>>& args)
{						  
	NewGen* classObject = new NewGen();		// TODO: malloc
	auto x = getCreaterOrderd(args);
	auto* creater = x.first;

	// TODO: 判断更准确 creater 应该为默认构造函数
	if (!args.empty() && !creater)
		return nullptr;  // 不匹配

	// 推导类
	auto a=generateClass(creater, x.second);
	classObject->type = a.first;

	classObject->construstor = creater ? creater->createCallGen(
		x.second->parameters,
		x.second->variableGen,
		classObject,
		a.second
	) : nullptr;
		
	if (args.empty() || classObject->construstor) 
		return classObject;
	throw std::runtime_error("类" + name + "没有合适的构造函数");
}

AstClass::CreaterOrdered AstClass::getCreaterOrderd(std::vector<std::pair<std::string, CodeGen*>>& args)
{
	AstFunction* creater = nullptr;
	AstFunction::OrderedParameters *ordered = nullptr;
	for (auto *x : _construstors) {
		if (ordered)
			throw std::runtime_error("类" + name + "的多个构造函数匹配参数");
		creater = x;
		ordered = x->orderParameters(args);
	}
	return CreaterOrdered(creater, ordered);
}

AstClass::InstancePair AstClass::generateClass(AstFunction * creater, AstFunction::OrderedParameters *ordered)
{
	if (_generated.first) return _generated;
	if (_templated) {
		auto a=_cached.find(reinterpret_cast<intptr_t>(creater));	   
		if (a != _cached.end()) return a->second;
	}

	ClassInstanceType* p= new ClassInstanceType(name);

	ClassContext* theClass = new ClassContext(_parent, p);
	theClass->pathName = _parent->pathName + "." + name;
	std::vector<Parameter> ord;

	Parameter param;
	bool isProctected = false;
	int idx = 0;

	for (auto i : block) {
		param.isProtected = isProctected;
		// 创建函数、变量索引
		auto x = dynamic_cast<AstFunction*>(i);
		if (x) {
			// 函数在被调用时才固化
			p->methds.insert(std::make_pair(x->name, x));
			continue;
		}

		auto v = dynamic_cast<AstDef*>(i);
		if (v) {
			for (auto a : v->vars) {
				param.name = a.name;
				param.type = v->type;
				param.value = a.value;
				param.index = idx++;
				p->members[a.name] = param;
			}
			continue;
		}

		auto y = dynamic_cast<AstProtected*>(i);
		if(y){
			isProctected = true;
			continue;
		}
		throw std::runtime_error("类内有未知的定义");
	}

	// 构造函数
	FunctionInstance* c= creater ? 
		creater->getFunctionInstance(ordered->parameters, ordered->variableGen, p) :
		nullptr;
	InstancePair pair(p, c);
	if (!_templated) _generated = pair;
	else {
		_cached[reinterpret_cast<intptr_t>(creater)] = pair;
	}
	return pair;
}




